# -*- coding: iso-8859-1 -*-

"""
Catanyste - Copyright 2008-2009 Julien RAIGNEAU
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance 
with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
the specific language governing permissions and limitations under the License. 
"""
__author__="Vincent"
__date__ ="$5 mars 2009 22:09:02$"

import hexacoord
from vertex import Vertex
from hexagone import Hexagone

class HexManager():
    """
    Manage hex list
    """

    def __init__(self, (UMAX,VMAX)):
        """
        1-D liste (U,V) is linearized into  I = U + V*linear
        x = mod(I/linear)
        y = ent(I/linear)
        """
        self.UMAX = UMAX
        self.VMAX = VMAX
        self.linear = int(UMAX)
        self.hexes = (UMAX * VMAX) * [0]   #1-D liste (U,V) is linearized into  U + V*linearize ##workf with neg value, but not checked theoritically
        self.vertexes1 = (UMAX * VMAX) * [0]
        self.vertexes2 = (UMAX * VMAX) * [0]

    def AddHexagone(self, hex):       #for backward compatibiliy
        u,v = hex.uv
        self.hexes[int(u)+self.linear*int(v)] = hex

    def UpdateHexagone(self, hex):    #for backward compatibiliy
        u,v = hex.uv
        self.hexes[int(u)+self.linear*int(v)] = hex

    def setHex(self, hex):       #this one should be use for both previous
        """
        Set an hex in the hex Manager according to hex.uv
        """
        u,v = hex.uv            #required : abs(u)<UMAX/2 ; abs(v)<VMAX/2
        self.hexes[int(u)+self.linear*int(v)] = hex

    def PrintClass(self):
        pass

    def GetHexagone(self, (u,v)):
        return self.hexes[int(u)+self.linear*int(v)]

    def GetVoisins(self,hex):
        return self.getHexNeighbours(self, hex)

    def getHexNeighbours(self, hex):
        """
        Returns neighbour hexes
        """
        neighbor_coord = hexacoord.hexnei(hex.uv)
        return tuple([self.hexes[int(u) + self.linear * int(v)] for u,v in neighbor_coord])

    def setVertex(self, vertex):  #set it in vertexes1 or vertexes2 according to hex coordinates
        u, v = vertex.uv
        u0, v0 = hexacoord.vertex2hex(vertex.uv)
        if u-u0 > 0:   # we have vertex1
            self.vertexes1[int(u0)+self.linear*int(v0)] = vertex
        else :          # we have vertex2
            self.vertexes2[int(u0)+self.linear*int(v0)] = vertex

#    def getVertex(self, (u,v)):
#        #print "found closest vertex is (%s, %s)\n" % (u,v)
#        try:
#            u0,v0 = hexacoord.vertex2hex((u,v))
#            #print "belong to hex (%s, %s)\n" % (u0v0[0],u0v0[1])
#            if u-u0 > 0:   # we have vertex1
#                return self.vertexes1[u0 + self.linear * v0]
#            else :          # we have vertex2
#                return self.vertexes2[u0 + self.linear * v0]
#        except hexacoord.NotVertexValueError :
#            return None

    def getHexesFromVertex(self, vertex):
        """
        return list_of_neighbour_hexes
        """
        hexes_coord = hexacoord.vertex2hexnei(vertex.uv)
        return tuple([self.hexes[int(u) + self.linear * int(v)] for u,v in hexes_coord])

    def computeVertexValues(self):
        """
        compute vertex proba attribute from surrounding hexes
        """
        Vertex.esperance = 0
        for k in Vertex.esperances: Vertex.esperances[k]=0
        for vertex in self.vertexes1+self.vertexes2:
            if vertex:
                hexes = self.getHexesFromVertex(vertex)
                vertex.esperance = 0
                for k in vertex.esperances: vertex.esperances[k]=0      #reset esperances
                for hex in hexes:
                    if hex:
                        if hex.resource == Hexagone.PORT3 or \
                           hex.resource == Hexagone.PORT2LUMBER or \
                           hex.resource == Hexagone.PORT2BRICK or \
                           hex.resource == Hexagone.PORT2WOOL or \
                           hex.resource == Hexagone.PORT2GRAIN or \
                           hex.resource == Hexagone.PORT2ORE :
                            vertex.port = hex.resource
                        elif 2<= hex.value <= 12 and not hex.hasthief and \
                           not hex.resource == Hexagone.DESERT and \
                           not hex.resource == Hexagone.SEA:
                            vertex.esperance += (6 - abs(hex.value - 7))
                            Vertex.esperance += (6 - abs(hex.value - 7))
                            vertex.esperances[hex.resource] += (6 - abs(hex.value - 7))
                            Vertex.esperances[hex.resource] += (6 - abs(hex.value - 7))

    def get_vertex(self, (u,v)):
        try:
            u0,v0 = hexacoord.vertex2hex((u,v))
            if -self.UMAX < u0 < self.UMAX and -self.VMAX < v0 < self.VMAX:
                if u-u0 > 0:   # we have vertex1
                    return self.vertexes1[int(u0)+self.linear*int(v0)]
                else :          # we have vertex2
                    return self.vertexes2[int(u0)+self.linear*int(v0)]
        except hexacoord.NotVertexValueError:
            return None

# XY is a View concept
#    def get_closest_vertex_with_xy(self, (x,y), d):
#        """
#        return vertex, which is closest is closest to (x,y) coordinate (at distance d)
#        return None if don't find it
#        """
#        ab = hexacoord.cart2hexa((x,y)) # assume shifting is done
#        uv = hexacoord.vertexround(ab)
#
#        #print "looking for closest vertex to (%s,%s) at distance %s\n" % (x, y,d)
##        uv = hexacoord.getClosestVertexFromXY((x,y), d)
#        if uv:
#            u,v = uv
#            #print "found closest vertex is (%s, %s)\n" % (u,v)
##            u0v0 = hexacoord.getClosestHexFromUV(uv)
#            u0v0 = hexacoord.hexround(uv)
#            if u0v0 :
#                u0,v0 = u0v0
#                #print "belong to hex (%s, %s)\n" % (u0v0[0],u0v0[1])
#                if u-u0 > 0:   # we have vertex1
#                    return self.vertexes1[int(u0)+self.linear*int(v0)]
#                else :          # we have vertex2
#                    return self.vertexes2[int(u0)+self.linear*int(v0)]
#        else : return
#
#    def get_closest_vertex_with_uv(self, (u,v)):
#        pass
